import LXCOM from '../../common/common.js'
import PolygonGraph from '../polygon.js'
import { CoordTRFUtil } from '../../common/tools/coordtool.js'
import Coord from '../../common/struct/coord.js'
import utilfuncs from '../../common/tools/utilfuncs.js'
var funcs = utilfuncs.UtilFuncs
import GlobalConst from '../../common/globalConst.js'
var global = GlobalConst.GlobalConst;
import {FillUtil} from '../../graph/paintutil/fillutil.js'
import {Strokeutil} from '../../graph/paintutil/strokeutil.js'

import {LGXEnums}  from '../../common/sysenum.js'


import multistar from '../../common/struct/basestruct/multistar.js'
import { GlobalVar } from '../../common/globalvar.js'

const CtrlPointKind = 1000;
//GlobalConst.BaseUnitPolygon = 0x030d02xx;//后两位表示角数
class MultiStarGraph extends PolygonGraph.PolygonGraph {
    constructor(type) {
        super(type);
        this.ctrlPoint = new LXCOM.LGXPoint();
        this.centerPt = new LXCOM.LGXPoint();
        this.width = 120;
        this.height = 120;
        this.m_graphType = LGXEnums.LGXGraphType.MultiStar_type;
        this.starCount = this._type & 0x000000ff;
        if (this.starCount == 3){
            this.innerRadius = 10;
        }
        else{
            this.innerRadius = 30;
        }
        this._fillDef.fillStyle = LGXEnums.LGXFillStyle.SOLID;
        this._fillDef.fillColor.clone(GlobalVar.visoDefaultFillColor);
    }

    display(map, mapInfo,forClip) {
        var scaling = mapInfo.getScaling();
        map.save();
        map.beginPath();
        var position = this.getPos();
        var lenth = position.posList.length;
        var pt = position.posList[0];
        var p0 = CoordTRFUtil.world2Screen(pt, mapInfo);
        map.moveTo(p0.x, p0.y);
        for (var i = 1; i < lenth; i++) {
            pt = position.posList[i];
            var p = CoordTRFUtil.world2Screen(pt, mapInfo);
            map.lineTo(p.x, p.y);
        }
        map.closePath();
        if (!forClip){
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this._fillDef, map, this, mapInfo, false);

            super.displayGraphScope(map, mapInfo);
            this.displayFeaturePoint(map, mapInfo);
        }
        map.restore();
    }

    disInSymbol(transformInfo,map, mapInfo,forClip) {
        var scaling = mapInfo.getScaling();
        map.save();
        map.beginPath();
        var position = this.getPosCopy();
        var lenth = position.posList.length;
        var pt = position.posList[0];
        var p0 = this.convertLocalPt2Screen(pt, mapInfo,transformInfo);
        map.moveTo(p0.x, p0.y);
        for (var i = 1; i < lenth; i++) {
            pt = position.posList[i];
            var p = this.convertLocalPt2Screen(pt, mapInfo,transformInfo);
            map.lineTo(p.x, p.y);
        }
        map.closePath();

        if (!forClip){
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this._fillDef, map, this, mapInfo, true,transformInfo);
        }
        map.restore();
    }

    calScope(mapscale) {
        var position = this.getPos();
        if (position.posList.length == 0){
            this.initData(mapscale);
        }
        super.calScope(mapscale);
    }

    initData(mapscale) {
        let xRadiusOuter = this.width / 2;
        let yRadiusOuter = this.height / 2;

        let xRadiusInner = this.innerRadius;
        let yRadiusInner = xRadiusInner * this.height / this.width;

        let stDgree = this.calStartDegree();

        let rotAngleDegree = this.getAngle();
        stDgree += rotAngleDegree;

        var position = this.getPos();
        position.clear();
        let angleSpan = 360 / this.starCount;
        let halfGap = angleSpan / 2;
        for (let i = 0; i < this.starCount; i++) {
            let degree = stDgree + i * angleSpan;
            let radVal = funcs.degree2Radian(degree);
            let x = this.centerPt.x + xRadiusOuter * Math.cos(radVal);
            let y = this.centerPt.y + yRadiusOuter * Math.sin(radVal);
            position.addPoint({ x, y });

            let nextDegree = degree + halfGap;
            let nextRadVal = funcs.degree2Radian(nextDegree);
            x = this.centerPt.x + xRadiusInner * Math.cos(nextRadVal);
            y = this.centerPt.y + yRadiusInner * Math.sin(nextRadVal);
            if (i == 0) {
                this.ctrlPoint.x = x;
                this.ctrlPoint.y = y;
            }
            position.addPoint({ x, y });
        }
        this.calScope(mapscale);
    }


    getLocalZone() {
        let rect = new LXCOM.LGXRect(0, 0, 0, 0);
        rect.left = (- this.width / 2);
        rect.bottom = (- this.height / 2);
        rect.right = (this.width / 2);
        rect.top = (this.height / 2);
        return rect;
    }

    calStartDegree() {
        let ptList = [];
        let xRadiusOuter = this.width/2;
        let yRadiusOuter = this.height/2;
        let angleSpan = 360 / this.starCount;
        for (let i = 0; i < this.starCount; i++) {
            let degree = i * angleSpan;
            let radVal = funcs.degree2Radian(degree);
            let x = xRadiusOuter * Math.cos(radVal);
            let y = yRadiusOuter * Math.sin(radVal);
            ptList.push({ x, y });
        }

        let maxyPt = ptList[0];
        let maxyIndex = 0;
        let maxy = maxyPt.y;
        for (let i = 1;i < ptList.length;i++){
            let pt = ptList[i];
            if (maxy < pt.y){
                maxy = pt.y;
                maxyIndex = i;
                maxyPt = pt;
            }
        }
        let vector = funcs.getVector({x:0,y:0},maxyPt);
        let degree = vector.angleFrmXAxisPositiveDir();
        return (90-degree);
    }


    displayFeaturePoint(map, mapInfo) {
        if (!this._selected || mapInfo.paintForGenerateICON) {
            return;
        }
        var ptlst = this.getScopeVertexPtLst(mapInfo.getScaling());
        this.displayDashLineRectScope(ptlst, map, mapInfo)
        ptlst.length = 0;
        ptlst = null;

        var point = CoordTRFUtil.world2Screen(this.ctrlPoint, mapInfo);
        this.drawFocusPoint(map, point.x, point.y, "#ffff00");
    }

    calculateSubKind(tPoint, scaling, mapscale) {
        var position = this.getPosCopy();
        var lenth = position.posList.length;
        if (lenth < 2) {
            return 0;
        }
        var seleKind = 0;
        var tAbsorbPt = new LXCOM.LGXPoint();
        tAbsorbPt.clone(tPoint);

        //多边形头尾是相连的
        var pPrePos = position.posList[0];
        let posList = position.posList;
        posList.push(pPrePos);

        let minDis = 100;
        var cmpGap = super.getSelCmpGap(scaling, mapscale);
        
        let dis = funcs.distancePoint(tPoint, this.ctrlPoint, scaling);
        if (dis <= cmpGap && dis >= 0 && dis <= minDis) {
            minDis = dis;
            seleKind = CtrlPointKind;
            tAbsorbPt.clone(this.ctrlPoint);
        }
        else{
            for (var i = 1; i < lenth; i++) {
                let pCntPos = posList[i];
                let dis = funcs.distanceLineSec4Visual(tPoint, pPrePos, pCntPos, scaling);
                if (dis <= cmpGap && dis >= 0 && dis <= minDis) {
                    minDis = dis;
                    tAbsorbPt.clone(tPoint);
                    seleKind = lenth + 1;
                }
                pPrePos = pCntPos;
            }
        }

        if (seleKind > 0) {
            tPoint.clone(tAbsorbPt);
        }

        return seleKind;
    }

    movePosOffset(tOffset, modCmdInfo) {
        if (this._selKind < 1) {
            return;
        }

        var position = this.getPos();
        var lenth = position.posList.length;
        if (this._selKind == CtrlPointKind) {
            let vector = funcs.getVector(this.centerPt, this.ctrlPoint);
            this.ctrlPoint.x += tOffset.x;
            this.ctrlPoint.y += tOffset.y;
            let dis = funcs.distancePoint(this.centerPt, this.ctrlPoint, 1);
            if (dis > global.ZERO_4E) {
                this.innerRadius = dis;
                this.initData(modCmdInfo.mapscale);
                this.calScope(modCmdInfo.mapscale);
            }
        }
        else if (this._selKind > lenth) {
            this.translate(tOffset, modCmdInfo.mapscale, false);
        }
    }

    translateSubData(tOffset, mapscale, multiTransFlag) {
        let preCnt = this._position.getCnt();
        this.ctrlPoint.x += tOffset.x;
        this.ctrlPoint.y += tOffset.y;

        this.centerPt.x += tOffset.x;
        this.centerPt.y += tOffset.y;
        return 0;
    }

    assignInfo(info) {
        super.assignInfo(info);
        this.centerPt.x = info.x;
        this.centerPt.y = info.y;
        this.width = info.width;
        this.height = info.height;
        this.innerRadius = info.innerRadius;
        this.starCount = info.starCount;
    }

    modifyAttribute(info, mapscale) {
        super.modifyCommonAttribute(info);
        this.centerPt.x = info.x;
        this.centerPt.y = info.y;
        this.width = info.width;
        this.height = info.height;
        this.innerRadius = info.innerRadius;
        this.starCount = info.starCount;
        this.calScope(mapscale);
    }

    toInfo() {
        var info = new multistar.MultiStarUnit();
        this.toInfo4InheritClass(info);
        info.x = this.centerPt.x;
        info.y = this.centerPt.y;
        info.width = this.width;
        info.height = this.height;
        info.starCount = this.starCount;
        info.innerRadius = this.innerRadius;
        return info;
    }

    rotateCoord(rotCnt, radAngle) {
        let scnt = funcs.rotate(this.centerPt, rotCnt, radAngle);
        this.centerPt.clone(scnt);
        super.rotateCoord(rotCnt, radAngle);
    }

    getMainFeaturePTLst(tFeaturePTLst,transformInfo) {
        let featurePT = this.convertPt2World(this.centerPt,transformInfo);
        tFeaturePTLst.push({pt:featurePT,kind:LGXEnums.AuxPointKind.center});
        super.getMainFeaturePTLst(tFeaturePTLst,transformInfo);
    }

    act2Mouse(mosEvnt, worldPos) {
        var ret = LGXEnums.LGXPlotState.NoneState;
        if (mosEvnt.type == LGXEnums.LGXMouseMode.LMouseDown) {
            if (this.getStart() == 0) {
                this.setStart(1);
                this.setFinish(1);
                this.centerPt.x = worldPos.x;
                this.centerPt.y = worldPos.y;
                ret = LGXEnums.LGXPlotState.FinistState;
                this.mouseDownTime = 1;
            }
        }
        this.calScope(1);
        this.notifyToObserver();
        return ret;
    }

    getLocalOrigin() {
        let pt = { x: 0, y: 0 };
        pt.x = this.centerPt.x;
        pt.y = this.centerPt.y;
        return pt;
    }

     //复制粘贴时，从复制源对象复制属性到本图形对应属性----虚函数，由实体继承类实现
     copySubPropFromBuf(info,tx,ty){
        this.width = info.width;
        this.height = info.height;
        this.innerRadius = info.innerRadius;
        this.starCount = info.starCount;
        this.centerPt.x = info.x + tx;
        this.centerPt.y = info.y + ty;
        this.copyCommnonPropFromBuf(info,tx,ty);
        this.initData(1);
    }
}


export default { MultiStarGraph }
